package hk.edu.polyu.comp.motioncapture.linklist;

public class List {

	private ListNode firstNode;
	private ListNode lastNode;
	private String name; // string like "list" used in printing
	private int MAX;
	private int size;

	// constructor creates empty List with "list" as the name
	public List() {
		this("List", 10000);
		size = 0;
	}

	// constructor creates an empty List with a name
	public List(String listName, int MAX) {
		name = listName;
		this.MAX = MAX;
		firstNode = lastNode = null;
		size = 0;
	}

	// insert Object at front of List
	public void insertAtFront(Object insertItem) {
		if (isEmpty()) {
			firstNode = lastNode = new ListNode(insertItem);
			size++;
		} else {
			if (size > MAX)
				removeFromFront();
			firstNode = new ListNode(insertItem, firstNode, true);
		}
	}

	// insert Object at end of List
	public void insertAtBack(Object insertItem) {
		if (isEmpty()) {
			firstNode = lastNode = new ListNode(insertItem);
			size++;
		} else {
			if (size > MAX)
				removeFromFront();
			lastNode = lastNode.nextNode = new ListNode(insertItem, lastNode,
					false);
		}
	}

	// remove first node from List
	public Object removeFromFront() throws EmptyListException {
		if (isEmpty())
			throw new EmptyListException(name);

		Object removedItem = firstNode.data;
		size--;

		// update references firstNode and lastNode
		if (firstNode == lastNode)
			firstNode = lastNode = null;
		else
			firstNode = firstNode.nextNode;

		return removedItem;
	}

	// remove last node from List
	public Object removeFromBack() throws EmptyListException {
		if (isEmpty())
			throw new EmptyListException(name);

		Object removedItem = lastNode.data;
		size--;

		// update references firstNode and lastNode
		if (firstNode == lastNode)
			firstNode = lastNode = null;
		else // locate new last node
		{
			ListNode current = firstNode;

			// loop while current node does not refer to lastNode
			while (current.nextNode != lastNode)
				current = current.nextNode;

			lastNode = current; // current is new lastNode
			current.nextNode = null;
		} // end else

		return removedItem;
	}

	// determine whether list is empty
	public boolean isEmpty() {
		return firstNode == null;
	}

	// output List contents
	public void print() {
		if (isEmpty()) {
			System.out.println("Empty");
			return;
		}

		ListNode current = firstNode;

		// while not at end of list, output current node's data
		while (current != null) {
			System.out.println("%s " + current.data);
			current = current.nextNode;
		}

		System.out.println("\n");
	}
}
